home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
408_01
/
article.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-06
|
32KB
|
1,157 lines
/*
SNEWS 1.91
article - routines to read and display an article
Copyright (C) 1991 John McCombs, Christchurch, NEW ZEALAND
john@ahuriri.gen.nz
PO Box 2708, Christchurch, NEW ZEALAND
Modifications copyright (C) 1993 Daniel Fandrich
<dan@fch.wimsey.bc.ca> or CompuServe 72365,306
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 1, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
See the file COPYING, which contains a copy of the GNU General
Public License.
Source is formatted with a tab size of 4.
*/
#include "defs.h"
#include "snews.h"
#include "pccharst.h"
#include <alloc.h>
#include <dir.h>
#include <io.h>
#include <ctype.h>
enum char_sets current_char_set = DEFAULT_CHAR_SET;
int active_code_page;
static char *empty_line = "\n"; /* static empty line structure */
void ReplyAddress(TEXT *tx, char *subject);
/*-------------------- set up the global code page vars --------------------*/
void select_code_page(void)
{
code_page_table = select_cp_table(active_code_page = get_code_page());
}
/*------------------------- read in an article -----------------------------*/
TEXT *load_article(char *fnx, long offset)
{
/*
* Open the file and read it. Save the author and organisation
* fill in the structures
*/
FILE *tmp_file;
char buf[256], lnbuf[256], *p, *s, *token;
TEXT *tx;
LINE *ln, *lz;
int ct, i;
tx = NULL;
ct = 0;
current_char_set = DEFAULT_CHAR_SET;
if ((tmp_file = flockopen(fnx, "rb")) != NULL) {
fseek(tmp_file, offset, SEEK_SET);
tx = xmalloc(sizeof(TEXT));
tx->top = NULL;
tx->start = NULL;
strcpy(tx->follow_up, "");
strcpy(tx->author, " ** none ** ");
strcpy(tx->organisation, " ** none ** ");
while (fgets(buf, sizeof(buf)-1, tmp_file) != NULL) {
if (strncmp(buf, "@@@@END", 7) == 0) break;
expand_tabs(buf, sizeof(buf)-1);
/*
* We now have a line of input. If the line is too long
* it is wrapped at spaces or '!'. The lines of text are
* stored in LINE structures
*/
p = &buf[0];
while (strlen(p) > 0) {
strcpy(lnbuf, p);
if (strlen(p) <= 80) {
strcpy(lnbuf, p);
*p = '\x00'; /* signal we're ready for a new line */
} else {
/* can we split the line at a nice spot (space , !) ? */
p += 79;
for (i = 79; i > 50; i--) {
if ((lnbuf[i] == ' ') || (lnbuf[i] == '!') ||
(lnbuf[i] == ','))
break;
p--;
}
/* can't split nicely -- split at the end of the line */
if (i <= 50) {
p += (79-i);
i = 79;
}
lnbuf[i] = '\x00';
}
/* is it the first line - if so int the TEXT structure */
if (ct == 0) {
ln = xmalloc(sizeof(LINE));
ln->last = NULL;
tx->top = ln;
} else {
lz = ln;
ln->next = xmalloc(sizeof(LINE));
ln = ln->next;
ln->last = lz;
}
ln->index = ct;
if (lnbuf[0] == '\n') /* is the line empty? */
ln->data = empty_line; /* yes, save malloc() overhead */
else {
ln->data = xmalloc(strlen(lnbuf)+1);
strcpy(ln->data, lnbuf);
}
/* Find first line of body */
if ((strlen(lnbuf) == 1) && (tx->start == NULL))
tx->start = ln;
ct++;
/* save the header info */
if ((tx->start == NULL) && (strnicmp("From:", lnbuf, 5) == 0)) {
s = lnbuf + 5;
while (*s && isspace(*s)) s++;
*(s + WHO_LENGTH - 1) = '\0';
strtok(strcpy(tx->author, s), "\n");
}
if ((tx->start == NULL) && ((strnicmp("Organisation:", lnbuf, 13) == 0) || (strncmp("Organization:", lnbuf, 13) == 0))) {
s = lnbuf + 13;
while (*s && isspace(*s)) s++;
*(s + ORG_LENGTH - 1) = '\0';
strtok(strcpy(tx->organisation, s), "\n");
}
if ((tx->start == NULL) && (strnicmp("Followup-To:", lnbuf, 12) == 0)) {
s = lnbuf + 12;
while (*s && isspace(*s)) s++;
*(s + sizeof(tx->follow_up) - 1) = '\0';
strtok(strcpy(tx->follow_up, s), "\n");
}
if ((tx->start == NULL) && (strnicmp("Content-Type:", lnbuf, 13) == 0)) {
s = lnbuf + 13;
while (*s && isspace(*s)) s++; /* kill leading spaces */
token = strtok(s, " ;\n");
while (token != NULL) {
if (strnicmp("charset=", token, 8) == 0) {
current_char_set = select_char_set(token+8);
break;
}
token = strtok(NULL, " ;\n");
}
}
}
}
ln->next = NULL;
tx->lines = ct;
fclose(tmp_file);
}
return(tx);
}
/*---------------------- deallocate article memory ------------------------*/
void free_article(TEXT *t)
{
LINE *l, *k;
l = t->top;
while (l != NULL) {
k = l;
l = l->next;
if (k->data != empty_line) /* don't free empty line pointer */
free(k->data);
free(k);
}
free(t);
}
/*---------------------------- read an article ----------------------------*/
enum exit_codes read_article(ACTIVE *gp, TEXT *tx, char *subject, int a_ct, int of_ct)
{
/*
* This routine allows the user to read an article
*/
LINE *this, *tmp; /* current thread */
enum exit_codes exit_code; /* why we are exiting the loop */
char sub_tmp[80]; /* new subject line */
int i, maxx;
this = tx->start;
if (this->next != NULL)
this = this->next; /* skip over blank line */
show_article(gp, tx, subject, this, a_ct, of_ct);
exit_code = EX_CONT;
while ((exit_code == EX_CONT) || (exit_code == EX_DUMMY)) {
exit_code = EX_CONT;
gotoxy(1,25);
switch (get_any_key()) {
case Fn1 :
case '?' :
case 'h' :
show_help(HELP_ARTICLES);
break;
case Fn2 :
show_values();
break;
case Fn3 :
if (current_char_set++ == US_ASCII)
current_char_set = 0;
break;
case Fn4 :
pipe_article(tx, my_stuff.hotpipe);
message("-- Done --");
break;
case UP_ARR :
if (this->last != NULL) {
this = this->last;
gotoxy(1,TEXT_LINE+PAGE_LENGTH-1);
delline();
gotoxy(1,TEXT_LINE);
insline();
clreol();
cputs(translate_line(this->data, current_char_set));
show_percent((int) ((100L * (this==NULL ? tx->lines+1 : min((this->index) + PAGE_LENGTH, tx->lines+1))) / ((tx->lines) + 1)));
}
exit_code = EX_DUMMY;
break;
case DN_ARR :
if (this->next != NULL &&
(this->index + PAGE_LENGTH < tx->lines ||
this->index <= tx->start->index)) {
this = this->next;
gotoxy(1,TEXT_LINE);